﻿// Copyright (c)  YISH. All rights reserved.
// Licensed under the MIT License, See License.txt in the project root for license information.

using System;
using System.Data;
using System.Diagnostics;
using System.Linq.Expressions;
using NSQL.Expressions;
using NSQL.Statements;

namespace NSQL.Query.Compiler
{
    public class StatementCompiler
    {
        private static readonly ParameterExpression DataSet = Expression.Variable(typeof(DataSet), "dataSet");
        public Func<DataSet, DataTable> Compile(ISelectStatement selectStatement)
        {
            var from = CompileFrom(selectStatement.TableSources);
            var where = CompileWhere(selectStatement.Predicate);
            var group = CompileGroup(selectStatement.GroupClause);
            var select = CompileSelect(selectStatement.Elements);
            var order = CompilerOrder(selectStatement.SortingClause);

            var step1 = Expression.Invoke(from, DataSet);
            var step2 = Expression.Invoke(where, step1);
            var step3 = Expression.Invoke(group, step2);
            var step4 = Expression.Invoke(select, step3);
            var step5 = Expression.Invoke(order, step4);
            return Expression.Lambda<Func<DataSet, DataTable>>(step5, DataSet).Compile();
        }

        private Expression<Func<DataSet, DataTable>> CompileFrom(TableSourceCollection tableSources)
        {
            Debug.Assert(tableSources.Count == 1 && tableSources[0] is Table);
            var table1 = (Table) tableSources[0];
            var t1 = Expression.Constant(table1.Name);
            var t2 = Expression.Property(Expression.Property(DataSet, nameof(System.Data.DataSet.Tables)), "", t1);

            return Expression.Lambda<Func<DataSet, DataTable>>(t2, DataSet);
        }

        private Expression<Func<DataTable, DataTable>> CompileWhere(IPredicateExpression expression)
        {
            throw new NotImplementedException();
        }

        private Expression<Func<DataTable, DataTable>> CompileGroup(GroupCollection groupItems)
        {
            throw new NotImplementedException();
        }

        private Expression<Func<DataTable, DataTable>> CompileSelect(SelectElementCollection selectElements)
        {
            throw new NotImplementedException();
        }

        private Expression<Func<DataTable, DataTable>> CompilerOrder(SortingCollection sortings)
        {
            throw new NotImplementedException();
        }
    }
}